package services

import (
	"log"
	"time"

	"ix-brow/models"
)

// 过期用户清理服务
type ExpiredUserService struct {
	API *IxBrowserAPI
}

// 创建新的过期用户清理服务
func NewExpiredUserService() *ExpiredUserService {
	return &ExpiredUserService{
		API: NewIxBrowserAPI(),
	}
}

// 查找并处理所有过期浏览器
func (s *ExpiredUserService) ProcessExpiredUsers() {
	log.Println("开始检查过期浏览器...")

	// 查找所有过期浏览器
	expiredBrowsers, err := models.FindExpiredBrowsers()
	if err != nil {
		log.Printf("查询过期浏览器时出错: %v", err)
		return
	}

	log.Printf("找到 %d 个过期浏览器:%v", len(expiredBrowsers),expiredBrowsers)

	// 按分组ID收集浏览器
	groupBrowsersMap := make(map[string][]models.Browser)
	for _, browser := range expiredBrowsers {
		groupID := browser.GroupID.String()
		groupBrowsersMap[groupID] = append(groupBrowsersMap[groupID], browser)
	}

	// 处理每个分组的过期浏览器
	for groupID, browsers := range groupBrowsersMap {
		if len(browsers) != 0 {
			// 处理过期浏览器 - 物理删除
			for _, browser := range browsers {
				// 如果浏览器有外部ID，在外部系统删除
				if browser.ExternalBrowserID > 0 {
					if err := s.API.DeleteBrowser(browser.ExternalBrowserID); err != nil {
						log.Printf("删除浏览器失败 (ID: %d): %v", browser.ExternalBrowserID, err)
					} else {
						log.Printf("已删除浏览器 (ID: %d)", browser.ExternalBrowserID)
					}
				}

				// 物理删除浏览器记录
				if err := models.DB.Unscoped().Delete(&browser).Error; err != nil {
					log.Printf("物理删除浏览器记录失败 (ID: %s): %v", browser.ID.String(), err)
				} else {
					log.Printf("已物理删除浏览器记录 (ID: %s)", browser.ID.String())
				}
				// 物理移除浏览器对应的代理信息
				if err := models.DB.Unscoped().Delete(&models.ProxyApplication{}).Where("browser_id = ?", browser.ID.String()).Error; err != nil {
					log.Printf("物理移除浏览器对应的代理信息失败 (ID: %s): %v", browser.ID.String(), err)
				} else {
					log.Printf("已物理移除浏览器对应的代理信息 (ID: %s)", browser.ID.String())
				}
			}
		}

		// 检查空分组并删除
		log.Println("检查空分组...")
		var group models.Group
		if err := models.DB.First(&group, "id = ?", groupID).Error; err == nil {
			// 查询分组中的浏览器数量
			var browserCount int64
			models.DB.Model(&models.Browser{}).
				Where("group_id = ?", group.ID).
				Count(&browserCount)
			// 如果分组中没有浏览器，删除分组
			if browserCount == 0 {
				// 删除外部系统分组
				if err := s.API.DeleteGroup(group.GroupID); err != nil {
					log.Printf("删除分组失败 (ID: %d): %v", group.GroupID, err)
				} else {
					log.Printf("已删除分组 (ID: %d)", group.GroupID)
				}

				// 物理删除分组记录
				if err := models.DB.Unscoped().Delete(&group).Error; err != nil {
					log.Printf("物理删除分组记录失败 (ID: %s): %v", group.ID.String(), err)
				} else {
					log.Printf("已物理删除分组记录 (ID: %s)", group.ID.String())
				}
			}
		}
		log.Println("检查清理空分组完成")

		// 检查没有分组的用户并删除
		log.Println("检查没有分组的用户...")
		var user models.User
		if err := models.DB.First(&user, "id = ?", group.UserID).Error; err == nil {
			var groupCount int64
			models.DB.Model(&models.Group{}).
				Where("user_id = ?", user.ID).
				Count(&groupCount)
	
			if groupCount == 0 {
				employee, err := s.API.FindEmployee(user.Username)
				if err == nil && employee != nil {
					// 删除员工
					if err := s.API.DeleteEmployee(employee.ID); err != nil {
						log.Printf("删除员工账号失败 (ID: %d): %v", employee.ID, err)
					} else {
						log.Printf("已删除员工账号 (ID: %d)", employee.ID)
					}
				}
				
				// 物理删除用户记录
				if err := models.DB.Unscoped().Delete(&user).Error; err != nil {
					log.Printf("物理删除用户记录失败 (ID: %s): %v", user.ID, err)
				} else {
					log.Printf("已物理删除用户记录 (ID: %s)", user.ID)
				}
			}
		}
	
		log.Printf("处理用户 %s (ID: %s) 的过期浏览器完成", user.Username, user.ID.String())
	}

	log.Println("过期浏览器处理完成")
}

// 启动定时检查
func (s *ExpiredUserService) StartScheduledCheck() {
	// 计算距离下一个凌晨的时间
	now := time.Now()
	next := time.Date(now.Year(), now.Month(), now.Day()+1, 0, 0, 0, 0, now.Location())
	duration := next.Sub(now)

	log.Printf("已安排过期浏览器检查任务，将在 %s 后执行（%s）", duration, next.Format("2006-01-02 15:04:05"))

	// 创建定时器
	timer := time.NewTimer(duration)

	// 在一个单独的goroutine中处理定时任务
	go func() {
		for {
			<-timer.C

			// 执行清理
			s.ProcessExpiredUsers()

			// 重置为下一个凌晨
			now = time.Now()
			next = time.Date(now.Year(), now.Month(), now.Day()+1, 0, 0, 0, 0, now.Location())
			duration = next.Sub(now)

			// 重置定时器
			timer.Reset(duration)

			log.Printf("下一次过期浏览器检查安排在 %s", next.Format("2006-01-02 15:04:05"))
		}
	}()
}
